package cn.xinfei.xdecision.engine.runner.datax;

import cn.xinfei.xdecision.common.model.datax.enums.CreditInquiryStatus;
import cn.xinfei.xdecision.common.model.datax.exception.XDecisionDataExceptionType;
import cn.xinfei.xdecision.constant.EngineResultEnum;
import cn.xinfei.xdecision.data.CreditDataApiInterface;
import cn.xinfei.xdecision.data.RiskDataApiInterface;
import cn.xinfei.xdecision.engine.runner.context.PipelineContextHolder;
import cn.xinfei.xdecision.engine.runner.context.XDecisionContext;
import cn.xinfei.xdecision.engine.runner.executor.model.InterVariableConstant;
import cn.xinfei.xdecision.engine.runner.executor.model.StateTransmitModel;
import cn.xinfei.xdecision.engine.runner.metadata.PrometheusTagsConstants;
import cn.xinfei.xdecision.engine.runner.service.DecisionResultService;
import cn.xinfei.xdecision.model.VariableApiRequest;
import cn.xinfei.xdecision.model.VariableApiResponse;
import cn.xinfei.xdecision.nacos.NacosSwitchProperties;
import com.alibaba.fastjson.JSONObject;
import com.dianping.cat.Cat;
import io.micrometer.core.instrument.MeterRegistry;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;
import cn.xinfei.xdecision.common.utils.util.JsonUtil;

@Data
@Slf4j
@Service
public class DataCreditFetchHandler extends RiskDataApiAdapter<VariableApiRequest, Boolean> {

    @Autowired
    private MeterRegistry meterRegistry;

    @Autowired
    private RiskDataApiInterface riskDataApiInterface;

    @Autowired
    private CreditDataApiInterface creditCollect;


    @Autowired
    private DecisionResultService decisionResultService;

    @Override
    protected Boolean exec(VariableApiRequest variableApiRequest) {

        StateTransmitModel stateContext = XDecisionContext.getContext().getStateContext();
        try {
            JSONObject inputParams = variableApiRequest.getInputParams();
            if(inputParams!=null){
                String creditChannel = inputParams.getString(InterVariableConstant.CREDIT_CHANNEL);
                if(StringUtils.isEmpty(creditChannel)){
                    log.info("creditChannel is null ,重新apply，inputParams={}", JsonUtil.toJson(inputParams));
                    stateContext.setEngineResultEnum(EngineResultEnum.CREDIT_PENDING_APPLY);
                    return false;
                }
            }
            VariableApiResponse dataApiResponse = creditCollect.fetchCreditVars(variableApiRequest);
            log.info("DataCreditFetchHandler.exec response={}", JsonUtil.toJson(dataApiResponse));
            if (null != dataApiResponse) {
                String code = dataApiResponse.getCode();
                if (String.valueOf(XDecisionDataExceptionType.SUCCESS.code).equals(code)
                        || CreditInquiryStatus.QUERY_SUCCESS.getCode().equals(code)) {
                    String variablesResponse = dataApiResponse.getVariablesResponse();
                    Map fieldInfo = JSONObject.parseObject(variablesResponse, Map.class);

                    if (NacosSwitchProperties.getNacosSwitchProperties().isDebugLog()) {
                        log.info("基于变量中心人行采集的数据，更新上下文。fieldInfo={}", variablesResponse);
                    }
                    PipelineContextHolder.putInContext("credit", fieldInfo);
                    stateContext.setEngineResultEnum(EngineResultEnum.PROCESSING);
                    return true;
//                } else if (String.valueOf(CreditInquiryStatus.QUERY_FAIL.getCode()).equals(code)) {
//                    log.warn("征信查询终止...");
//                    meterRegistry.counter("xengine_xdata_credit_end_total").increment();
//                    String bizId = PipelineContextHolder.getRequestId();
//                    decisionResultService.updateDecisionResultCodeById(bizId, null, EngineResultEnum.CREDIT_PENDING_END.getCode());
//                    stateContext.setEngineResultEnum(EngineResultEnum.CREDIT_PENDING_END);
                } else if (String.valueOf(CreditInquiryStatus.INIT.getCode()).equals(code)
                        || String.valueOf(CreditInquiryStatus.QUERYING.getCode()).equals(code)) {
                    //继续查询：00，01
                    stateContext.setEngineResultEnum(EngineResultEnum.CREDIT_PENDING_FETCH);
//                    stateContext.setEngineResultEnum(EngineResultEnum.CREDIT_PENDING_APPLY);
                    return false;

                } else if (String.valueOf(CreditInquiryStatus.EMPTY.getCode()).equals(code)
                        || String.valueOf(CreditInquiryStatus.OVERDUE.getCode()).equals(code)
                        || String.valueOf(CreditInquiryStatus.QUERY_FAIL.getCode()).equals(code)) {
                    //重新申请:03,04,56002
                    //03 终止：老决策引擎是终止，新决策引擎会重新上报
                    //04 拉数据时间过期，没有拉取到数据
                    //56002 三个月内没有上报记录
//                    stateContext.setEngineResultEnum(EngineResultEnum.CREDIT_PENDING_FETCH);
                    stateContext.setEngineResultEnum(EngineResultEnum.CREDIT_PENDING_APPLY);//重新上报
//                    stateContext.setEngineResultEnum(EngineResultEnum.REVIEW);//阻塞住不再重试
                    return false;
//                    stateContext.setEngineResultEnum(EngineResultEnum.PROCESSING);
//                    return true;
                }
                meterRegistry.counter("xdecision_credit_fetch_total", PrometheusTagsConstants.XDATA_API_TOTAL_TAGS.and("code", code)).increment();
            } else {
                meterRegistry.counter("xdecision_credit_fetch_total", PrometheusTagsConstants.XDATA_API_TOTAL_TAGS.and("code", "null")).increment();
            }
            //重新申请
            stateContext.setEngineResultEnum(EngineResultEnum.CREDIT_PENDING_APPLY);
        } catch (Exception e) {
            log.error("DataCreditFetchHandler exception. error={},variableApiRequest={}", e.getMessage(), JsonUtil.toJson(variableApiRequest), e);

            //重新申请
            stateContext.setEngineResultEnum(EngineResultEnum.CREDIT_PENDING_APPLY);
            Cat.logError(e);
            meterRegistry.counter("xdecision_credit_fetch_total", PrometheusTagsConstants.XDATA_API_TOTAL_TAGS.and("code", "exception")).increment();

            throw e;
        }

        return false;
    }
}
